package com.starinside.wp.service.impl;

import com.alibaba.fastjson.JSON;
import com.dotflat.utils.DateUtil;
import com.starinside.wp.domain.Children;
import com.starinside.wp.domain.ChildrenExtendInfo;
import com.starinside.wp.domain.ChildrenNurseryInfoRecord;
import com.starinside.wp.domain.WorkDate;
import com.starinside.wp.foundation.constant.ChildrenConstant;
import com.starinside.wp.foundation.dto.StaffDTO;
import com.starinside.wp.foundation.exception.BusinessException;
import com.starinside.wp.foundation.model.ErrorCode;
import com.starinside.wp.foundation.query.base.PagerQuery;
import com.starinside.wp.foundation.vo.ContractVoV2;
import com.starinside.wp.repository.*;
import com.starinside.wp.service.NurseryInfoRecordService;
import com.starinside.wp.utils.AssertUtil;
import com.starinside.wp.utils.HttpClientUtil;
import com.starinside.wp.utils.RemoteCallUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * *******************************
 * Created by Tim.
 * form com.matt
 * on 2018/10/31
 * *******************************
 */
@Service
@Slf4j
public class NurseryInfoRecordServiceImpl implements NurseryInfoRecordService {

    @Autowired
    private ChildrenRepository childrenRepository;

    @Autowired
    private ChildrenExtendInfoRepository childrenExtendInfoRepository;

    @Autowired
    private ChildrenNurseryInfoRecordRepository childrenNurseryInfoRecordRepository;

    @Autowired
    private ChildrenContractInfoRecordRepository childrenContractInfoRecordRepository;

    @Autowired
    private WorkDateRepository workDateRepository;


    @Value("${server.crm.url}")
    private String crmServerURL;


    @Override
    public Map getBalance(String ticket,  String childrenId, String beginDate, String endDate, PagerQuery pagerQuery) {
        Children children = childrenRepository.getOne(childrenId);

        Map attendanceMap = new HashMap();
        attendanceMap.put("areaId", children.getAreaId());
        attendanceMap.put("clientelesId", children.getCrmClienteleId());
        //合同当月的应出勤数
        List<Map> mapList1 = RemoteCallUtil.callOfList(crmServerURL + "/api/other_system/attendance_count", attendanceMap, null, Map.class, "获取合同信息失败");

        Integer shouldAttendanceCount = 0;

        for (int k = 0; k <mapList1.size() ; k++) {
            String clienteleId = String.valueOf(mapList1.get(k).get("clienteleId"));
            if (StringUtils.equals(children.getCrmClienteleId(),clienteleId)){
                shouldAttendanceCount = (Integer) mapList1.get(k).get("count");
            }
        }

        Page<ChildrenNurseryInfoRecord> page = getList( childrenId, beginDate, endDate, pagerQuery);

        //普通课程
        int type0 = 0;
        //延长合同
        int type1 = 0;
        //入户扣课
        int type2 = 0;

        for (int i = 0; i < page.getContent().size(); i++) {
            if (page.getContent().get(i).getType() == 0 && (page.getContent().get(i).getStatus() == 1 || page.getContent().get(i).getStatus() == 2)) {
                type0 = type0 + page.getContent().get(i).getEffectDay();
            }
            if (page.getContent().get(i).getType() == 1) {
                type1 = type1 + page.getContent().get(i).getEffectDay();
            }
            if (page.getContent().get(i).getType() == 2) {
                type0 = type2 + type0;
                type2 = type2 + (~((page.getContent().get(i).getEffectDay() / 2) - 1));
            }
        }
        Map map = new HashMap();
        map.put("areaId", children.getAreaId());
        map.put("clienteleId", children.getCrmClienteleId());
        map.put("date", beginDate);
        //查询用户合同在开始时间内的托班合同
        List<ContractVoV2> callOfList = RemoteCallUtil.callOfList(crmServerURL + "/api/other_system/get_clienteleId_contract_list", map, null, ContractVoV2.class, "获取合同信息失败");
        for (int i = 0; i < callOfList.size(); i++) {
            //合同的最大请假数
            Integer  surplusOriginalLeaveDay = childrenContractInfoRecordRepository.getMaxSurplusOriginalLeaveDay(callOfList.get(i).getId());
            if (surplusOriginalLeaveDay>0){
                callOfList.get(i).setSurplusOriginalLeaveDay(surplusOriginalLeaveDay);
            }
        }

        Map m = new HashMap();
        //合同原始工作日天数
        m.put("initialDay", shouldAttendanceCount);
        //课时顺延数量
        m.put("reduceAddDay", type1 + type2);
        //今日之后工作日数量
        m.put("attendDay", type0);
        //合同集合
        m.put("contractList", callOfList);

        m.put("page", page);
        return m;
    }

    public Page<ChildrenNurseryInfoRecord> getList( String childrenId, String beginDate, String endDate, PagerQuery pagerQuery) {
        PageRequest pageRequest = PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize(),
                Sort.by("created").descending());
        Specification<ChildrenNurseryInfoRecord> specification = new Specification<ChildrenNurseryInfoRecord>() {
            @Override
            public Predicate toPredicate(Root<ChildrenNurseryInfoRecord> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (StringUtils.isNotBlank(childrenId)) {
                    predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("childrenId"), childrenId)));
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                if (StringUtils.isNotBlank(beginDate) && StringUtils.isNotBlank(endDate)) {
                    predicates.add(criteriaBuilder.ge(root.get("beginDate").as(Long.class), Long.parseLong(sdf.format(DateUtil.parseToDate(beginDate)))));
                    predicates.add(criteriaBuilder.le(root.get("endDate").as(Long.class), Long.parseLong(sdf.format(DateUtil.parseToDateMilisV2(endDate)))));
                }

                query.where(predicates.toArray(new Predicate[predicates.size()]));
                query.orderBy(criteriaBuilder.desc(root.get("created")));
                return query.getRestriction();
            }
        };
        Page<ChildrenNurseryInfoRecord> page = childrenNurseryInfoRecordRepository.findAll(specification, pageRequest);
        return page;
    }
}
